package com.vehiclesecure.controller;

import com.vehiclesecure.model.User;
import com.vehiclesecure.model.Vehicle;
import com.vehiclesecure.service.UserService;
import com.vehiclesecure.service.VehicleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 车辆信息控制器
 * 处理车辆信息的CRUD操作和用户绑定功能
 */
@RestController
@RequestMapping("/api/vehicles")
public class VehicleController {

    private final VehicleService vehicleService;
    private final UserService userService;

    @Autowired
    public VehicleController(VehicleService vehicleService, UserService userService) {
        this.vehicleService = vehicleService;
        this.userService = userService;
    }

    /**
     * 获取当前登录用户
     * @return 当前登录用户对象
     */
    private User getCurrentUser() {
        String email = SecurityContextHolder.getContext().getAuthentication().getName();
        // 不直接强制转换，而是通过email重新查询用户对象
        return userService.findByEmail(email)
                .orElseThrow(() -> new RuntimeException("当前用户不存在: " + email));
    }

    /**
     * 创建新车辆
     * @param vehicle 车辆信息
     * @return 创建的车辆
     */
    @PostMapping
    @PreAuthorize("hasAnyRole('USER', 'ADMIN')")
    public ResponseEntity<Vehicle> createVehicle(@RequestBody Vehicle vehicle) {
        try {
            User currentUser = getCurrentUser();
            
            // 设置车主信息
            vehicle.setOwnerId(currentUser.getId());
            vehicle.setOwnerName(currentUser.getFirstName() + " " + currentUser.getLastName());
            vehicle.setOwnerEmail(currentUser.getEmail());
            vehicle.setCreatedAt(LocalDateTime.now());
            vehicle.setUpdatedAt(LocalDateTime.now());
            
            Vehicle createdVehicle = vehicleService.createVehicle(vehicle);
            
            // 将车辆ID添加到用户的vehicleIds列表中
            if (currentUser.getVehicleIds() == null) {
                currentUser.setVehicleIds(new ArrayList<>());
            }
            currentUser.getVehicleIds().add(createdVehicle.getId());
            userService.updateUser(currentUser);
            
            return ResponseEntity.ok(createdVehicle);
        } catch (RuntimeException e) {
            return ResponseEntity.badRequest().body(null);
        }
    }

    /**
     * 获取所有车辆
     * @return 车辆列表
     */
    @GetMapping
    @PreAuthorize("hasAnyRole('USER', 'ADMIN')")
    public ResponseEntity<List<Vehicle>> getAllVehicles() {
        User currentUser = getCurrentUser();
        
        // 管理员可以查看所有车辆，普通用户只能查看自己有权限的车辆
        if (currentUser.getRole().equals(User.Role.ADMIN)) {
            List<Vehicle> vehicles = vehicleService.getAllVehicles();
            return ResponseEntity.ok(vehicles);
        } else {
            List<Vehicle> vehicles = vehicleService.getUserAccessibleVehicles(currentUser.getId());
            return ResponseEntity.ok(vehicles);
        }
    }

    /**
     * 根据ID获取车辆
     * @param id 车辆ID
     * @return 车辆信息
     */
    @GetMapping("/{id}")
    @PreAuthorize("hasAnyRole('USER', 'ADMIN', 'SERVICE_PROVIDER')")
    public ResponseEntity<Vehicle> getVehicleById(@PathVariable String id) {
        User currentUser = getCurrentUser();
        
        // 服务商不能访问全部车辆信息，只能访问维修相关的数据
        if (currentUser.getRole() == User.Role.SERVICE_PROVIDER) {
            return ResponseEntity.status(403).build(); // 服务商无权访问车辆基本信息
        }
        
        // 检查用户是否有权限访问该车辆
        if (!vehicleService.hasAccessToVehicle(currentUser.getId(), id) && 
            !currentUser.getRole().equals(User.Role.ADMIN)) {
            return ResponseEntity.status(403).build();
        }
        
        Optional<Vehicle> vehicle = vehicleService.getVehicleById(id);
        return vehicle.map(ResponseEntity::ok)
                     .orElse(ResponseEntity.notFound().build());
    }

    /**
     * 根据VIN码获取车辆
     * @param vin VIN码
     * @return 车辆信息
     */
    @GetMapping("/vin/{vin}")
    @PreAuthorize("hasAnyRole('USER', 'ADMIN')")
    public ResponseEntity<Vehicle> getVehicleByVin(@PathVariable String vin) {
        User currentUser = getCurrentUser();
        
        Optional<Vehicle> vehicle = vehicleService.getVehicleByVin(vin);
        if (vehicle.isPresent()) {
            // 检查用户是否有权限访问该车辆
            if (!vehicleService.hasAccessToVehicle(currentUser.getId(), vehicle.get().getId()) && 
                !currentUser.getRole().equals(User.Role.ADMIN)) {
                return ResponseEntity.status(403).build();
            }
            return ResponseEntity.ok(vehicle.get());
        }
        return ResponseEntity.notFound().build();
    }

    /**
     * 根据车牌号获取车辆
     * @param licensePlate 车牌号
     * @return 车辆信息
     */
    @GetMapping("/plate/{licensePlate}")
    @PreAuthorize("hasAnyRole('USER', 'ADMIN', 'SERVICE_PROVIDER')")
    public ResponseEntity<Vehicle> getVehicleByLicensePlate(@PathVariable String licensePlate) {
        User currentUser = getCurrentUser();
        
        // 服务商不能访问全部车辆信息
        if (currentUser.getRole() == User.Role.SERVICE_PROVIDER) {
            return ResponseEntity.status(403).build(); // 服务商无权访问车辆基本信息
        }
        
        Optional<Vehicle> vehicle = vehicleService.getVehicleByLicensePlate(licensePlate);
        if (vehicle.isPresent()) {
            // 检查用户是否有权限访问该车辆
            if (!vehicleService.hasAccessToVehicle(currentUser.getId(), vehicle.get().getId()) && 
                !currentUser.getRole().equals(User.Role.ADMIN)) {
                return ResponseEntity.status(403).build();
            }
            return ResponseEntity.ok(vehicle.get());
        }
        return ResponseEntity.notFound().build();
    }

    /**
     * 更新车辆信息
     * @param id 车辆ID
     * @param vehicle 更新的车辆信息
     * @return 更新后的车辆
     */
    @PutMapping("/{id}")
    @PreAuthorize("hasAnyRole('USER', 'ADMIN')")
    public ResponseEntity<Vehicle> updateVehicle(@PathVariable String id, @RequestBody Vehicle vehicle) {
        User currentUser = getCurrentUser();
        
        // 检查用户是否有权限修改该车辆
        if (!vehicleService.hasAccessToVehicle(currentUser.getId(), id) && 
            !currentUser.getRole().equals(User.Role.ADMIN)) {
            return ResponseEntity.status(403).build();
        }
        
        try {
            Vehicle updatedVehicle = vehicleService.updateVehicle(id, vehicle);
            return ResponseEntity.ok(updatedVehicle);
        } catch (RuntimeException e) {
            return ResponseEntity.badRequest().body(null);
        }
    }

    /**
     * 删除车辆
     * @param id 车辆ID
     * @return 响应结果
     */
    @DeleteMapping("/{id}")
    @PreAuthorize("hasAnyRole('USER', 'ADMIN')")
    public ResponseEntity<Map<String, String>> deleteVehicle(@PathVariable String id) {
        User currentUser = getCurrentUser();
        
        // 检查用户是否有权限删除该车辆
        if (!vehicleService.hasAccessToVehicle(currentUser.getId(), id) && 
            !currentUser.getRole().equals(User.Role.ADMIN)) {
            return ResponseEntity.status(403).build();
        }
        
        try {
            vehicleService.deleteVehicle(id);
            return ResponseEntity.ok(Map.of("message", "车辆删除成功"));
        } catch (RuntimeException e) {
            return ResponseEntity.badRequest().body(Map.of("error", e.getMessage()));
        }
    }

    /**
     * 获取当前用户的车辆
     * @return 车辆列表
     */
    @GetMapping("/my")
    @PreAuthorize("hasAnyRole('USER', 'ADMIN')")
    public ResponseEntity<List<Vehicle>> getMyVehicles() {
        User currentUser = getCurrentUser();
        List<Vehicle> vehicles = vehicleService.getVehiclesByOwner(currentUser.getId());
        return ResponseEntity.ok(vehicles);
    }

    /**
     * 获取用户有权限访问的车辆
     * @return 车辆列表
     */
    @GetMapping("/accessible")
    @PreAuthorize("hasAnyRole('USER', 'ADMIN', 'SERVICE_PROVIDER')")
    public ResponseEntity<List<Vehicle>> getAccessibleVehicles() {
        User currentUser = getCurrentUser();
        
        // 服务商不能访问车辆基本信息
        if (currentUser.getRole() == User.Role.SERVICE_PROVIDER) {
            return ResponseEntity.ok(new ArrayList<>()); // 返回空列表
        }
        
        List<Vehicle> vehicles = vehicleService.getUserAccessibleVehicles(currentUser.getId());
        return ResponseEntity.ok(vehicles);
    }

    /**
     * 绑定车辆到当前用户
     * @param vehicleId 车辆ID
     * @return 响应结果
     */
    @PostMapping("/{vehicleId}/bind")
    @PreAuthorize("hasAnyRole('USER', 'ADMIN')")
    public ResponseEntity<Map<String, String>> bindVehicleToUser(@PathVariable String vehicleId) {
        User currentUser = getCurrentUser();
        
        try {
            vehicleService.bindVehicleToUser(vehicleId, currentUser.getId());
            return ResponseEntity.ok(Map.of("message", "车辆绑定成功"));
        } catch (RuntimeException e) {
            return ResponseEntity.badRequest().body(Map.of("error", e.getMessage()));
        }
    }

    /**
     * 解绑车辆与当前用户的关联
     * @param vehicleId 车辆ID
     * @return 响应结果
     */
    @DeleteMapping("/{vehicleId}/unbind")
    @PreAuthorize("hasAnyRole('USER', 'ADMIN')")
    public ResponseEntity<Map<String, String>> unbindVehicleFromUser(@PathVariable String vehicleId) {
        User currentUser = getCurrentUser();
        
        try {
            vehicleService.unbindVehicleFromUser(vehicleId, currentUser.getId());
            return ResponseEntity.ok(Map.of("message", "车辆解绑成功"));
        } catch (RuntimeException e) {
            return ResponseEntity.badRequest().body(Map.of("error", e.getMessage()));
        }
    }

    /**
     * 标记车辆为被盗
     * @param vehicleId 车辆ID
     * @return 响应结果
     */
    @PostMapping("/{vehicleId}/mark-stolen")
    @PreAuthorize("hasAnyRole('USER', 'ADMIN')")
    public ResponseEntity<Map<String, String>> markVehicleAsStolen(@PathVariable String vehicleId) {
        User currentUser = getCurrentUser();
        
        // 检查用户是否有权限操作该车辆
        if (!vehicleService.hasAccessToVehicle(currentUser.getId(), vehicleId) && 
            !currentUser.getRole().equals(User.Role.ADMIN)) {
            return ResponseEntity.status(403).build();
        }
        
        try {
            vehicleService.markVehicleAsStolen(vehicleId);
            return ResponseEntity.ok(Map.of("message", "车辆已标记为被盗"));
        } catch (RuntimeException e) {
            return ResponseEntity.badRequest().body(Map.of("error", e.getMessage()));
        }
    }

    /**
     * 取消车辆被盗标记
     * @param vehicleId 车辆ID
     * @return 响应结果
     */
    @PostMapping("/{vehicleId}/unmark-stolen")
    @PreAuthorize("hasAnyRole('USER', 'ADMIN')")
    public ResponseEntity<Map<String, String>> unmarkVehicleAsStolen(@PathVariable String vehicleId) {
        User currentUser = getCurrentUser();
        
        // 检查用户是否有权限操作该车辆
        if (!vehicleService.hasAccessToVehicle(currentUser.getId(), vehicleId) && 
            !currentUser.getRole().equals(User.Role.ADMIN)) {
            return ResponseEntity.status(403).build();
        }
        
        try {
            vehicleService.unmarkVehicleAsStolen(vehicleId);
            return ResponseEntity.ok(Map.of("message", "车辆被盗标记已取消"));
        } catch (RuntimeException e) {
            return ResponseEntity.badRequest().body(Map.of("error", e.getMessage()));
        }
    }

    /**
     * 更新车辆位置
     * @param vehicleId 车辆ID
     * @param locationData 位置数据
     * @return 响应结果
     */
    @PostMapping("/{vehicleId}/location")
    @PreAuthorize("hasAnyRole('USER', 'ADMIN')")
    public ResponseEntity<Map<String, String>> updateVehicleLocation(
            @PathVariable String vehicleId,
            @RequestBody Map<String, Double> locationData) {
        User currentUser = getCurrentUser();
        
        // 检查用户是否有权限操作该车辆
        if (!vehicleService.hasAccessToVehicle(currentUser.getId(), vehicleId) && 
            !currentUser.getRole().equals(User.Role.ADMIN)) {
            return ResponseEntity.status(403).build();
        }
        
        try {
            Double latitude = locationData.get("latitude");
            Double longitude = locationData.get("longitude");
            
            if (latitude == null || longitude == null) {
                return ResponseEntity.badRequest().body(Map.of("error", "纬度和经度不能为空"));
            }
            
            vehicleService.updateVehicleLocation(vehicleId, latitude, longitude);
            return ResponseEntity.ok(Map.of("message", "车辆位置更新成功"));
        } catch (RuntimeException e) {
            return ResponseEntity.badRequest().body(Map.of("error", e.getMessage()));
        }
    }

    /**
     * 搜索车辆
     * @param keyword 搜索关键词
     * @return 车辆列表
     */
    @GetMapping("/search")
    @PreAuthorize("hasAnyRole('USER', 'ADMIN')")
    public ResponseEntity<List<Vehicle>> searchVehicles(
            @RequestParam(required = false) String keyword) {
        User currentUser = getCurrentUser();
        
        List<Vehicle> vehicles = vehicleService.searchVehicles(keyword);
        
        // 过滤用户有权限访问的车辆
        if (!currentUser.getRole().equals(User.Role.ADMIN)) {
            vehicles = vehicles.stream()
                    .filter(v -> vehicleService.hasAccessToVehicle(currentUser.getId(), v.getId()))
                    .toList();
        }
        
        return ResponseEntity.ok(vehicles);
    }

    /**
     * 根据品牌获取车辆
     * @param brand 品牌
     * @return 车辆列表
     */
    @GetMapping("/brand/{brand}")
    @PreAuthorize("hasRole('ADMIN')")
    public ResponseEntity<List<Vehicle>> getVehiclesByBrand(@PathVariable String brand) {
        List<Vehicle> vehicles = vehicleService.getVehiclesByBrand(brand);
        return ResponseEntity.ok(vehicles);
    }

    /**
     * 根据状态获取车辆
     * @param status 状态
     * @return 车辆列表
     */
    @GetMapping("/status/{status}")
    @PreAuthorize("hasRole('ADMIN')")
    public ResponseEntity<List<Vehicle>> getVehiclesByStatus(@PathVariable String status) {
        List<Vehicle> vehicles = vehicleService.getVehiclesByStatus(status);
        return ResponseEntity.ok(vehicles);
    }
}